﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace GXRTBTC.PublicClassLibrary.Model
{
    /// <summary>
    /// 衍生告警模型
    /// </summary>
    public class DerivedRealAlarm
    {
        /// <summary>
        /// 规则derived_alarm_info表id
        /// </summary>
        public int derivedId { get; set; } = -1;
        /// <summary>
        /// 规则名称
        /// </summary>
        public string rulerName { get; set; } = "";
        /// <summary>
        /// 规则是否在用
        /// </summary>
        public bool used { get; set; } = true;
        /// <summary>
        /// 子系统ID
        /// </summary>
        public int subSystemId { get; set; } = -1;
        /// <summary>
        /// 关联方式 1:主次关联  2:阈值关联 3:频次关联，关联字典表
        /// </summary>
        public string relationMethod { get; set; } = "";
        /// <summary>
        /// 告警标题、描述，对应dynamic_data表alarm_title
        /// </summary>
        public string alarmTitle { get; set; } = "";
        /// <summary>
        /// 告警标题ID
        /// </summary>
        public string alarmTitleId { get; set; } = "0";
        public string subSysId { get; set; } = "-1";
        public string devTypeId { get; set; } = "";
        /// <summary>
        /// 设备类型名称
        /// </summary>
        public string devTypeName { get; set; } = "台站";
        public int alarmId { get; set; } = -1;
        public string alarmType { get; set; } = "";
        /// <summary>
        /// 子系统
        /// </summary>
        public string sub_system { get; set; } = "";
        /// <summary>
        /// 告警持续时间，超过才算真正告警
        /// </summary>
        //public int activeTimeout { get; set; } = 15;
        public int activeTimeout { get; set; } = 5;
        /// <summary>
        /// 连接判断，连通超过才算真的恢复正常
        /// </summary>
        public int connTimeout { get; set; } = 3;
        /// <summary>
        /// 规则描述
        /// </summary>
        public string rulerDescribe { get; set; } = "";
        /// <summary>
        /// 告警标题
        /// 告警标题：[衍生告警]-XXX
        /// </summary>
        public string derivedAlarmTitle { get; set; } = "";
        /// <summary>
        /// 衍生告警级别
        /// </summary>
        public int derivedAlarmLevel { get; set; } = 2;
        /// <summary>
        /// 基础表告警级别
        /// </summary>
        public int alarmLevel { get; set; } = 2;
        /// <summary>
        /// 衍生告警清除方式 1:子告警全部清除后衍生告警清除  2:子告警清除低于指定值，衍生告警清除 3:子告警清除任一条，衍生告警清除，关联字典表
        /// </summary>
        public int clearMode { get; set; } = -1;
        /// <summary>
        /// 源告警条件ID组，用逗号隔开，与关系，来自source_alarm_condition_info
        /// key:source_alarm_condition_info表id
        /// value;SourceAlarmCondition
        /// </summary>
        public Dictionary<int, SourceAlarmCondition> SourceAlarmConditions { get; set; } = new Dictionary<int, SourceAlarmCondition>();
        /// <summary>
        /// 上一次告警
        /// </summary>
        public bool preAlarm { get; set; } = false;
        /// <summary>
        /// 当前衍生告警derivedId是否告警
        /// </summary>
        public bool derivedAlarm { get; set; } = false;
        /// <summary>
        /// 告警跳动时间
        /// 用于判断
        /// </summary>
        public DateTime ChangeTime { get; set; } = DateTime.Now;
        /// <summary>
        /// 告警实际开始时间
        /// </summary>
        public DateTime AlarmTimeBgn { get; set; } = DateTime.Now;
        /// <summary>
        /// 告警实际结束时间
        /// </summary>
        public DateTime AlarmTimeEnd { get; set; } = DateTime.Now;
        /// <summary>
        /// 当前衍生告警derivedId是否告警
        /// 判断告警超过activeTimeout秒
        /// </summary>
        /// <param name="isAlarm">当前告警状态</param>
        /// <param name="newTime"></param>
        /// <returns></returns>
        public bool CheckAlarm(bool currentAlarm, DateTime newTime)
        {
            //非无法ping通和上报超时时，activeTimeout和connTimeout设置为0
            //因为台站断连和主次关联等告警，都是其他告警引发的，不需要再等待
            if (alarmId != 123 && alarmId != 124)
            {
                activeTimeout = 0;
                connTimeout = 0;
            }

            //告警有变化时，赋值开始、结束时间
            if (currentAlarm != preAlarm)
            {
                //告警跳动时间记录
                ChangeTime = DateTime.Now;

                //当前为告警、已结束的，则认为新告警开始
                if (currentAlarm && !derivedAlarm)
                {
                    //跳变，且当前告警，且历史非告警时，记录开始时间
                    AlarmTimeBgn = newTime;
                }
            }

            //结束时间
            AlarmTimeEnd = newTime;

            //当前如果告警，则用告警持续时间，否则用告警结束持续时间
            int timeout = currentAlarm ? activeTimeout : connTimeout;
            //告警最新跳动时间，主要用于判断告警
            TimeSpan ts = DateTime.Now - ChangeTime;
            //告警持续时间是否超过设定的间隔
            //derivedAlarm = ts.TotalSeconds > timeout ? currentAlarm : derivedAlarm;
            derivedAlarm = Math.Abs(ts.TotalSeconds) > timeout ? currentAlarm : derivedAlarm;

            //记录当前连接状态
            preAlarm = currentAlarm;

            //未启用规则，则不告警
            if (!used)
            {
                derivedAlarm = false;
            }

            return derivedAlarm;
        }
    }

    /// <summary>
    /// 衍生告警关联条件
    /// </summary>
    public class SourceAlarmCondition
    {
        /// <summary>
        /// 衍生告警表ID
        /// </summary>
        public int SourceAlarmId { get; set; } = -1;
        /// <summary>
        /// 设备类型id,alarm_basic_info也有相关信息
        /// </summary>
        public int deviceTypeId { get; set; } = -1;
        /// <summary>
        /// 设备厂家ID
        /// </summary>
        public int VenderId { get; set; } = -1;
        /// <summary>
        /// 告警标题ID集合，来自alarm_basic_info，或关系
        /// </summary>
        public List<int> AlarmIds { get; set; } = new();
        public List<int> RelateAlarmIds { get; set; } = new();
    }
}
